package com.chennan.leading.common.util;

import org.apache.commons.lang3.StringUtils;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;

/**
 * @author chennan
 * @createTime 2022年03月24日 15:54:00
 */
public class TimeUtils {

    public static final String DATE_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMAT_TYPE1 = "yyyy-MM-dd HH:mm";
    public static final String DATE_FORMAT_TYPE2 = "yyyy-MM-dd";
    public static final String DATE_FORMAT_TYPE3 = "yyMMdd";
    public static final String DATE_FORMAT_TYPE4 = "yyyyMMdd HH:mm:ss";
    public static final String DATE_FORMAT_TYPE5 = "yyyyMMdd";
    public static final String DATE_FORMAT_TYPE6 = "yyyy.MM.dd";
    public static final String DATE_FORMAT_TYPE7 = "yyyy.MM.dd HH:mm:ss";
    public static final String DATE_FORMAT_TYPE8 = "yyyy/MM/dd";
    public static final String DATE_FORMAT_TYPE9 = "yyyy-MM-dd HH:mm:ss.SSS";

    private static final DateTimeFormatter DATE_TIME_FORMATTER;

    static {
        DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT_FULL);
    }

    /**
     * 根据时间格式返回对应的String类型的时间
     *
     * @param localDateTime
     * @return
     */
    public static String format(LocalDateTime localDateTime) {
        if (null == localDateTime) {
            return null;
        }
        return localDateTime.format(DATE_TIME_FORMATTER);
    }

    public static String format(LocalDateTime localDateTime, String dateTimeFormatter) {
        if (null == localDateTime) {
            return null;
        }
        return localDateTime.format(DateTimeFormatter.ofPattern(dateTimeFormatter));
    }

    public static String format(LocalDate localDate, String dateTimeFormatter) {
        if (null == localDate) {
            return null;
        }
        return localDate.format(DateTimeFormatter.ofPattern(dateTimeFormatter));
    }

    public static LocalDateTime parseLocalDateTime(String time, String dateTimeFormatter) {
        if (StringUtils.isEmpty(time)) {
            return null;
        }
        try {
            return LocalDateTime.parse(time, DateTimeFormatter.ofPattern(dateTimeFormatter));
        } catch (Exception e) {
            return null;
        }
    }

    public static LocalDate parseLocalDate(String date, String dateTimeFormatter) {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        try {
            return LocalDate.parse(date, DateTimeFormatter.ofPattern(dateTimeFormatter));
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 转换字符串到LocalDate
     *
     * @param date
     *            要转换的字符串 支持 yyyy-MM-dd、yyyyMMdd、yyyy.MM.dd、yyyy/MM/dd、Date 类构造支持格式
     * @return java.time.LocalDate
     * @author xingguo.yang
     * @date 2020/11/18
     */
    public static LocalDate tryParseLocalDate(String date) {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        LocalDate localDate = parseLocalDate(date, DATE_FORMAT_TYPE2);
        if (null == localDate) {
            localDate = parseLocalDate(date, DATE_FORMAT_TYPE5);
        }
        if (null == localDate) {
            localDate = parseLocalDate(date, DATE_FORMAT_TYPE6);
        }
        if (null == localDate) {
            localDate = parseLocalDate(date, DATE_FORMAT_TYPE8);
        }
        if (null == localDate) {
            try {

                Date parseDate = new Date(date);
                Instant instant = parseDate.toInstant();
                ZoneId zone = ZoneId.systemDefault();
                LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone);
                localDate = localDateTime.toLocalDate();
            } catch (Exception ex) {
                return null;
            }
        }
        return localDate;

    }

    /**
     * 转换字符串到LocalDateTime
     *
     * @param date
     *            转换的时间字符串
     * @return java.time.LocalDateTime
     * @author xingguo.yang
     * @date 2021/3/2
     */
    public static LocalDateTime tryParseLocalDateTime(String date) {
        if (StringUtils.isEmpty(date)) {
            return null;
        }
        LocalDateTime localDateTime = parseLocalDateTime(date, DATE_FORMAT_FULL);
        if (null == localDateTime) {
            localDateTime = parseLocalDateTime(date, DATE_FORMAT_TYPE9);
        }
        if (null == localDateTime) {
            try {
                Date parseDate = new Date(date);
                Instant instant = parseDate.toInstant();
                ZoneId zone = ZoneId.systemDefault();
                localDateTime = LocalDateTime.ofInstant(instant, zone);
            } catch (Exception ex) {
                return null;
            }
        }
        return localDateTime;

    }
}
